package spring.chatroom.java_chatroom.server;

import cn.hutool.json.JSONUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import spring.chatroom.java_chatroom.common.utils.SessionIdAndUserId;
import spring.chatroom.java_chatroom.common.utils.UserIdsAndSessionId;
import spring.chatroom.java_chatroom.mapper.FriendTableMapper;
import spring.chatroom.java_chatroom.common.utils.WaitToSendUtil;
import spring.chatroom.java_chatroom.common.utils.WebSocketSessionManagerUtil;
import spring.chatroom.java_chatroom.pojo.model.AddFriendInfo;
import spring.chatroom.java_chatroom.pojo.model.MsgInfo;
import spring.chatroom.java_chatroom.pojo.response.Response;

import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.Objects;

@Slf4j
@Service
public class MesSendServer {

    @Autowired
    private FriendTableMapper friendTableMapper;

    public void sendMsg(WebSocketSession session, MsgInfo c) throws IOException, InterruptedException {
        session.sendMessage(contentToTextMessage(c));
    }

    public void sendMsg(MsgInfo c) throws IOException, InterruptedException {
        List<Integer> ids = SessionIdAndUserId.get(c.getSessionId());

        //根据SessionId来获取到userId
        if (ids == null) {
            ids = friendTableMapper.getFriendTableBySessionId(c.getSessionId());
            SessionIdAndUserId.push(c.getSessionId(), ids);

            ids.sort(Integer::compareTo);
            UserIdsAndSessionId.push(ids.hashCode(), c.getSessionId());
        }

        boolean flg = false;

        for (Integer id : ids) {
            //先获取到会话的session对象 一个WebSocketSession就表示的是一个服务器和客户端的连接
            WebSocketSession web = WebSocketSessionManagerUtil.getAttribute(id);

            //为空说明没有登录 为0就表示是somebody 那就不用在发了
            if (web == null) {
                if (id == 0) {
                    flg = true;
                }
                continue;
            }

            //防止某人发的又发给他
            if (id == 0 && "某人".equals(c.getUserName())) {
                continue;
            }

            log.info("send id: {} sendMsg: {}", id, c);

            try {
                web.sendMessage(contentToTextMessage(c));
            }catch (Exception e){
                log.error("在发送消息是出现了错误  error: {}", e.getMessage(), e);
                WebSocketSessionManagerUtil.removeAttribute(web);
                web.close();
            }
        }

        //是发送不在的消息
        if (flg) {
            Thread.sleep(300);
            logoffCue(c);
        }
    }


    //不用储存再服务器中
    private void logoffCue(MsgInfo c) throws IOException {
        WebSocketSession web = WebSocketSessionManagerUtil.getAttribute(c.getUserId());

        //没有登录 借用在线好友的WebSocketSession 来发送未登录的信息
        MsgInfo msg = new MsgInfo();
        BeanUtils.copyProperties(c, msg);
        msg.setUserId(0);
        msg.setContent("某人不在哦，你可以call管理员叫醒我哦 ε٩(๑> ₃ <)۶з");
        msg.setUserName("某人");
        web.sendMessage(contentToTextMessage(msg));
    }

    /**
     * 转发发送方发送的好友请求
     * @param targetId 接受好友的id 通过他来获取到对应的websocket连接
     * @param content  请求信息
     */
    public void tranFriendReq(Integer targetId, AddFriendInfo content) throws IOException {
        //获取到targetId的webSocket
        WebSocketSession attribute = WebSocketSessionManagerUtil.getAttribute(targetId);

        WaitToSendUtil.setAttribute(targetId, content);

        if (attribute == null) {
            return;
        }

        //发送给他
        attribute.sendMessage(contentToTextMessage(content));
    }

    /**
     * @param userId 接受方id
     * @param friendId 发送方id
     */
    public void addFriendAgree(Integer userId, Integer friendId) throws IOException {
        //发送方的session
        WebSocketSession attribute = WebSocketSessionManagerUtil.getAttribute(friendId);

        deleteAddFriendReq(userId, friendId);

        attribute.sendMessage(contentToTextMessage(Map.of("type", "addFriendAgree")));
    }

    public void deleteAddFriendReq(Integer userId, Integer friendId) {
        List<Object> attribute1 = WaitToSendUtil.getAttribute(userId);

        // 删除对应的friendId对应的请求
        for (int i = 0; i < attribute1.size(); i++) {
            AddFriendInfo o = (AddFriendInfo) attribute1.get(i);
            if (Objects.equals(o.getSendUser().getUserId(), friendId)) {
                attribute1.remove(i);
                break;
            }
        }
    }

    //转为websocket发送的格式
    private TextMessage contentToTextMessage(Object content) {

        String json = JSONUtil.toJsonStr(Response.success(content));

        return new TextMessage(json);
    }
}
